<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 
        概念:
        发布订阅模式是指希望接收通知的对象(订阅者)基于一个主题通过自定义事件订阅该主题, 发布事件的对象(发布者), 通过发布主题事件的方法通知各个订阅该主题的对象(订阅者)


        发布者的消息是不会直接发送到订阅者手里, 这就意味着发布者和订阅者是不知道彼此的存在, 他们直接存在第三个组件(调度中心或中间件), 调度中心维持发布者和订阅者的联系, 通过发布者的发布消息, 相对应的发放给订阅者

        思路:
        1. 创建一个对象(事件派发器)
        2. 在该对象上创建一个调度中心(事件中心), 其实就是一个缓存列表
        3. on 方法用来把函数都加到缓存列表中(订阅者注册事件到事件中心)
    -->

    <script>
        // 实现事件派发器
        class EventEmitter {
            constructor() {
                // 事件中心
                this.list = {
                    // 属性名(自定义事件的名称) : 属性值(自定义事件的回调函数)
                    // 淘宝直播 : [() => {商家}, () => {用户}]
                }
            }

            // 定义订阅方法
            $on(event, callback) {
                // event 订阅的自定义事件
                // callback 接收自定义事件的回调函数
                // 默认值 (查看自定义事件是否存在)
                this.list[event] = this.list[event] || [];
                // 将订阅者的回调函数push到事件中心
                this.list[event].push(callback);
                console.log(this.list);
            }
            // 定义发布方法(执行自定义事件)
            $emit(event) {
                // event 自定义事件名称
                if (this.list[event]) {
                    this.list[event].forEach(item => {
                        // item就是缓存列表中的每一个回调函数
                        item();
                    })
                }
            }
        }

        // 实例化(事件派发器)
        let e = new EventEmitter();


        //    vm.$on("xxx", (res) => {
        //         console.log(res);
        //     })

        // 商家
        // 订阅者(淘宝平台提醒商家订阅的活动商品已经上架)
        e.$on('淘宝直播', function fn1() {
            console.log("淘宝商家: 直播开始商品已经上架, 用户可以购买商品了");
        });
        e.$on('抖音直播', function fn1() {
            console.log("抖音商家: 直播开始商品已经上架, 用户可以购买商品了");
        });

        // 用户
        // 订阅者(提醒用户直播开始)
        e.$on("淘宝直播", function fn2() {
            console.log("淘宝用户: 直播开始, 准点开始抢购");
        });
        e.$on("抖音直播", function fn2() {
            console.log("抖音用户: 直播开始, 准点开始抢购");
        });


        // 发布者 (淘宝平台发布事件)
        setTimeout(() => {
            e.$emit("淘宝直播");
        }, 3000)

        setTimeout(() => {
            e.$emit("抖音直播");
        }, 1000)
    </script>
</body>

</html>